#ifndef OLOLO_FALLING_THINGS_HPP
#define OLOLO_FALLING_THINGS_HPP
#include <memory>
#include <stdlib.h>
//этот класс = игровая площадка для игры в падающиую херню
//он умеет играть только в игры где есть задний, передний слои
//и много летающих хреней между ними
class falling_things {
public:
	//абстрактный интерфейс ко всему во что можно тыкать
	//это просто неизвестный летающий по экрану объект
	class object {
	public:
		virtual ~object(){}
		//возвращает true если объект пора уничтожить
		virtual bool out_of_screen(falling_things& ctx)=0;
		//передвижения всякие. dt - время за которое надо сместиться
		virtual void animate(falling_things& ctx, double dt)=0;
		//проверка на попадание. при попадании объект будет удален позже
		//это нужно для того, например, чтоб превратить шаарик в кучу 
		//блестящего говна после попадания. говно не сразу пропадет
		//и поэтому объект будет помнить где его сбили и рисовать это говно
		virtual bool hit_test(falling_things& ctx, float x, float y)=0;
		//тут рисуют
		virtual void paint()=0;
	protected:
		object(){}
	private:
		object(const object&);
		object& operator =(const object&);
	};
	//при создании игры уже надо знать, какого размера игровое поле
	falling_things(float w, float h);
	//создание нового бублика-эта функция сама может решать какой объект
	//создать - вдруг у нас будут не только шарики но и ролики.
	virtual std::auto_ptr<object> create();
	//отрисовка заднего фона
	virtual void paint();
	//отрисовка переднего плана, возможно еще и какие-то
	//операции с аккумулятором сюда пустить
	virtual void post_paint();
	//обработчики событий:
	//	изменение размеров игровой области
	//	анимация всякая
	//  поправка координат тыка мышью на случай
	//	реакция на движение мыши
	//в последних двух случаях предусмотрена возможность скролить область
	virtual void resize(float width, float height);
	virtual void animate(double dt);
	virtual void adjust_mouse_click(float& x, float& y);
	virtual void mouse_motion(float dt, float& x, float& y, float dx, float dy);
	
	//эти функции оценивают, сколько штуковин должно быть на экране
	//и сколько их можно добавить за единицу времени
	virtual unsigned int expected_number_of_bubles();
	virtual unsigned int max_bubles_to_spawn(double dt);
	
	//проверка выхода за пределы поля
	bool is_visible(float left,float bottom, float right, float top);
	//очки
	void add_score(unsigned int d){m_score+=d;}
private:
	//внезапно набранные очки
	unsigned int m_score;
	//границы игрового поля
	float  m_top, m_bottom, m_left, m_right;
	//время последнего спавна бубликов
	double m_last_spawn_latency;
};


#endif
